/**
 * Copyright (c) 2015-present, Facebook, Inc.
 * All rights reserved.
 *
 * This source code is licensed under the BSD-style license found in the
 * LICENSE file in the root directory of this source tree. An additional grant
 * of patent rights can be found in the PATENTS file in the same directory.
 *
 * @format
 */

'use strict'
const crypto = require('crypto')
const fs = require('fs')
const path = require('path')

function md5 (str) {
    return crypto.createHash('md5').update(str).digest('hex')
}

//读配置
function getOrCreateModuleIdsJsonObj (filepath) {
    if (fs.existsSync(filepath)) {
        let data = fs.readFileSync(filepath, 'utf-8')
        return JSON.parse(data)
    } else {
        return {}
    }
}

//写配置
function saveModuleIdsJsonObj (filepath, jsonObj) {
    let data = JSON.stringify(jsonObj)
    try {
        fs.writeFileSync(filepath, data)
        console.log('write moduleIds json success')
    } catch (e) {
        throw e
    }
}
//目录层次是： /node_modules/metro-bunder/src/lib/createModuleIdFactory.js
//todo 后面改为根据`node_modules`寻找根目录，不然新老架构工程不一样
let rootPath = path.resolve(__dirname, '../../../../..')
console.error('rootPath', rootPath)

//定义模块id和模块路径映射关系
let moduleIdsJsonObj = {}
//模块id存储文件路径
let moduleIdsJsonObjPath = path.resolve(rootPath, 'moduleIdMap.json')

function createModuleIdFactory () {
    let currentModuleId = 0
    //从文件中读取moduleId映射关系
    moduleIdsJsonObj = getOrCreateModuleIdsJsonObj(moduleIdsJsonObjPath)
    //遍历找到最大的moduleId
    for (let key in moduleIdsJsonObj) {
        currentModuleId = currentModuleId > moduleIdsJsonObj[key].id ? currentModuleId : moduleIdsJsonObj[key].id
    }

    return (_ref) => {
        let modulePath = _ref.path
        //使用相对路径的hash值作为moduleKey
        let start = rootPath.length
        const moduleRPath = modulePath.substring(start)
        const moduleKey = md5(moduleRPath)
        if (moduleIdsJsonObj[moduleKey] == null) { //查找moduleId
            console.log("新增js模块：",modulePath, moduleKey, currentModuleId)
            moduleIdsJsonObj[moduleKey] = {
                id: ++currentModuleId,
                path: moduleRPath
            }
            saveModuleIdsJsonObj(moduleIdsJsonObjPath, moduleIdsJsonObj)
        }else{
            if (moduleIdsJsonObj[moduleKey].path !== moduleRPath) { //如果hash相同但path不同（概率极低），则报错
                throw new Error('hash碰撞问题发生，不可继续')
            }
        }
        return moduleIdsJsonObj[moduleKey].id
    }
}

module.exports = createModuleIdFactory
